describe('前后端真实交互测试 - 基于实际数据库', () => {
  let testData

  before(() => {
    // 加载测试数据
    cy.fixture('test-data').then((data) => {
      testData = data
    })

    // 准备测试数据库
    cy.setupTestDatabase()
    cy.verifyTestDataExists()
  })

  after(() => {
    // 清理测试数据
    cy.cleanupTestDatabase()
  })

  beforeEach(() => {
    cy.clearLocalStorage()
  })

  describe('🔄 完整SMT业务流程测试', () => {
    it('应该完成从订单查询到扫描记录的完整流程', () => {
      // 1. 测试订单查询API
      cy.log('📋 步骤1: 查询测试订单')
      cy.apiRequest('GET', `/api/smt/order/${testData.orders.valid.orderNo}`)
        .then((response) => {
          expect(response.status).to.equal(200)
          
          if (response.body.code === testData.responseCodes.success) {
            cy.log('✅ 订单查询成功')
            expect(response.body.data).to.have.property('orderNo')
            expect(response.body.data.orderNo).to.equal(testData.orders.valid.orderNo)
          } else {
            cy.log(`⚠️ 订单查询返回业务错误码: ${response.body.code}`)
            expect([
              testData.responseCodes.orderNotFound,
              testData.responseCodes.dataNotFound
            ]).to.include(response.body.code)
          }
        })

      // 2. 测试作业员验证API
      cy.log('👨‍🔧 步骤2: 验证测试作业员')
      cy.apiRequest('GET', `/api/workers/${testData.operators.valid.operatorId}`)
        .then((response) => {
          expect(response.status).to.equal(200)
          
          if (response.body.code === testData.responseCodes.success) {
            cy.log('✅ 作业员验证成功')
            expect(response.body.data).to.have.property('operatorId')
            expect(response.body.data.operatorName).to.equal(testData.operators.valid.operatorName)
          } else {
            cy.log(`⚠️ 作业员验证返回业务错误码: ${response.body.code}`)
          }
        })

      // 3. 测试BOM查询API
      cy.log('📦 步骤3: 查询BOM信息')
      const { orderNo, machineId, surface } = testData.orders.valid
      cy.apiRequest('GET', `/api/smt/bom/${orderNo}/${machineId}/${surface}`)
        .then((response) => {
          expect(response.status).to.equal(200)
          
          if (response.body.code === testData.responseCodes.success) {
            cy.log('✅ BOM查询成功')
            expect(response.body.data).to.be.an('array')
          } else {
            cy.log(`⚠️ BOM查询返回业务错误码: ${response.body.code}`)
            expect([
              testData.responseCodes.bomNotFound,
              testData.responseCodes.dataNotFound
            ]).to.include(response.body.code)
          }
        })

      // 4. 测试扫描记录提交API
      cy.log('🔍 步骤4: 提交扫描记录')
      const scanRecord = {
        orderNo: testData.orders.valid.orderNo,
        mounterId: testData.orders.valid.machineId,
        smtSide: 'TOP',
        partId: testData.parts.valid[0].partId,
        rollNo: testData.parts.valid[0].rollNo,
        lotNo: testData.parts.valid[0].lotNo,
        operatorId: testData.operators.valid.operatorId,
        scanTime: new Date().toISOString()
      }

      cy.apiRequest('POST', '/api/smt/scan-record', scanRecord)
        .then((response) => {
          expect(response.status).to.equal(200)
          expect(response.body).to.have.property('code')
          
          if (response.body.code === testData.responseCodes.success) {
            cy.log('✅ 扫描记录提交成功')
          } else {
            cy.log(`📝 扫描记录提交返回业务码: ${response.body.code} - ${response.body.message}`)
            // 这可能是正常的业务逻辑（如数据验证失败等）
          }
        })
    })
  })

  describe('⚠️ 异常场景测试', () => {
    it('应该正确处理不存在的订单', () => {
      cy.log('❌ 测试不存在的订单')
      cy.apiRequest('GET', `/api/smt/order/${testData.orders.invalid.orderNo}`)
        .then((response) => {
          expect(response.status).to.equal(200) // HTTP状态码仍为200
          expect(response.body.code).to.not.equal(testData.responseCodes.success)
          cy.log(`✅ 正确返回业务错误码: ${response.body.code}`)
        })
    })

    it('应该正确处理不存在的作业员', () => {
      cy.log('❌ 测试不存在的作业员')
      cy.apiRequest('GET', `/api/workers/${testData.operators.invalid.operatorId}`)
        .then((response) => {
          expect(response.status).to.equal(200) // HTTP状态码仍为200
          expect(response.body.code).to.not.equal(testData.responseCodes.success)
          cy.log(`✅ 正确返回业务错误码: ${response.body.code}`)
        })
    })

    it('应该处理重复扫描记录提交', () => {
      const scanRecord = {
        orderNo: testData.orders.valid.orderNo,
        mounterId: testData.orders.valid.machineId,
        smtSide: 'TOP',
        partId: testData.parts.valid[0].partId,
        rollNo: testData.parts.valid[0].rollNo,
        lotNo: testData.parts.valid[0].lotNo,
        operatorId: testData.operators.valid.operatorId,
        scanTime: new Date().toISOString()
      }

      cy.log('📝 第一次提交扫描记录')
      cy.apiRequest('POST', '/api/smt/scan-record', scanRecord)
        .then((firstResponse) => {
          expect(firstResponse.status).to.equal(200)
          cy.log(`第一次提交结果: ${firstResponse.body.code}`)

          cy.log('📝 第二次提交相同扫描记录')
          cy.apiRequest('POST', '/api/smt/scan-record', scanRecord)
            .then((secondResponse) => {
              expect(secondResponse.status).to.equal(200)
              cy.log(`第二次提交结果: ${secondResponse.body.code}`)
              
              // 如果第一次成功，第二次应该检测到重复
              if (firstResponse.body.code === testData.responseCodes.success) {
                expect(secondResponse.body.code).to.equal(testData.responseCodes.scanRecordDuplicate)
                cy.log('✅ 正确检测到重复提交')
              }
            })
        })
    })
  })

  describe('📊 数据一致性验证', () => {
    it('应该验证前后端数据传输的一致性', () => {
      // 测试特殊字符和中文字符处理
      const testScanRecord = {
        orderNo: 'TEST123',
        mounterId: 'M05',
        smtSide: 'TOP',
        partId: '特殊零件-R1',
        rollNo: 'ROLL测试001',
        lotNo: 'LOT批次001',
        operatorId: testData.operators.valid.operatorId,
        scanTime: new Date().toISOString(),
        remarks: '测试备注：包含中文和特殊字符!@#$%^&*()'
      }

      cy.apiRequest('POST', '/api/smt/scan-record', testScanRecord)
        .then((response) => {
          expect(response.status).to.equal(200)
          cy.log(`特殊字符处理结果: ${response.body.code} - ${response.body.message}`)
          
          // 验证响应中的中文字符没有乱码
          expect(response.body.message).to.be.a('string')
          if (response.body.data && response.body.data.remarks) {
            expect(response.body.data.remarks).to.include('测试备注')
          }
        })
    })

    it('应该验证时间戳格式处理', () => {
      const invalidTimeFormats = [
        '2024-13-32 25:99:99', // 无效日期时间
        'invalid-time-format',  // 完全无效格式
        '',                     // 空字符串
        null                    // null值
      ]

      invalidTimeFormats.forEach((invalidTime, index) => {
        const scanRecord = {
          orderNo: testData.orders.valid.orderNo,
          mounterId: testData.orders.valid.machineId,
          smtSide: 'TOP',
          partId: `TIMETEST${index}`,
          rollNo: `ROLLTIME${index}`,
          lotNo: `LOTTIME${index}`,
          operatorId: testData.operators.valid.operatorId,
          scanTime: invalidTime
        }

        cy.log(`⏰ 测试无效时间格式 ${index + 1}: ${invalidTime}`)
        cy.apiRequest('POST', '/api/smt/scan-record', scanRecord)
          .then((response) => {
            expect(response.status).to.equal(200)
            cy.log(`时间格式验证结果: ${response.body.code}`)
            // 预期应该返回时间格式错误码
          })
      })
    })
  })

  describe('🚀 性能和并发测试', () => {
    it('应该处理并发API请求', () => {
      const concurrentRequests = []
      const requestCount = 5

      // 创建多个并发请求
      for (let i = 0; i < requestCount; i++) {
        concurrentRequests.push(
          cy.apiRequest('GET', `/api/smt/order/${testData.orders.valid.orderNo}`)
        )
      }

      // 验证所有请求都能正常处理
      Promise.all(concurrentRequests).then((responses) => {
        responses.forEach((response, index) => {
          expect(response.status).to.equal(200)
          cy.log(`并发请求${index + 1}状态: ${response.status}, 业务码: ${response.body.code}`)
        })
        cy.log(`✅ ${requestCount}个并发请求全部完成`)
      })
    })

    it('应该在合理时间内响应API请求', () => {
      const startTime = Date.now()
      
      cy.apiRequest('GET', `/api/smt/order/${testData.orders.valid.orderNo}`)
        .then((response) => {
          const responseTime = Date.now() - startTime
          expect(response.status).to.equal(200)
          expect(responseTime).to.be.lessThan(3000) // 3秒内响应
          cy.log(`⚡ API响应时间: ${responseTime}ms`)
        })
    })
  })

  describe('🔐 安全性测试', () => {
    it('应该处理SQL注入攻击尝试', () => {
      const sqlInjectionAttempts = [
        "'; DROP TABLE T_ORDER; --",
        "' OR '1'='1",
        "'; DELETE FROM T_SMT_USER WHERE 1=1; --"
      ]

      sqlInjectionAttempts.forEach((maliciousInput, index) => {
        cy.log(`🛡️ SQL注入测试 ${index + 1}: ${maliciousInput}`)
        cy.apiRequest('GET', `/api/smt/order/${encodeURIComponent(maliciousInput)}`)
          .then((response) => {
            expect(response.status).to.equal(200)
            // 应该返回正常的业务错误码，而不是内部错误
            expect(response.body.code).to.not.equal(testData.responseCodes.internalError)
            cy.log(`安全测试结果: ${response.body.code}`)
          })
      })
    })

    it('应该处理XSS攻击尝试', () => {
      const xssPayloads = [
        '<script>alert("XSS")</script>',
        '"><script>alert("XSS")</script>',
        'javascript:alert("XSS")'
      ]

      xssPayloads.forEach((payload, index) => {
        const scanRecord = {
          orderNo: testData.orders.valid.orderNo,
          mounterId: testData.orders.valid.machineId,
          smtSide: 'TOP',
          partId: payload,
          rollNo: `XSSTEST${index}`,
          lotNo: `XSSLOT${index}`,
          operatorId: testData.operators.valid.operatorId,
          scanTime: new Date().toISOString()
        }

        cy.log(`🛡️ XSS测试 ${index + 1}`)
        cy.apiRequest('POST', '/api/smt/scan-record', scanRecord)
          .then((response) => {
            expect(response.status).to.equal(200)
            // 验证响应中没有执行恶意脚本
            if (response.body.message) {
              expect(response.body.message).to.not.include('<script>')
            }
            cy.log(`XSS防护测试结果: ${response.body.code}`)
          })
      })
    })
  })
})